﻿using System;
using System.Collections.Generic;
using MSDNWebcast.Models;
using System.Xml;

namespace MSDNWebcast.Service
{
    /// <summary>
    /// 课程服务
    /// </summary>
    public class CourseService
    {
        /// <summary>
        /// 所有课程
        /// </summary>
        private List<Course> m_Courses;

        /// <summary>
        /// info.xml 文件路径
        /// </summary>
        private readonly string m_InfoXmlPath;

        /// <summary>
        /// 可用的文件类型
        /// </summary>
        private readonly List<FileType> m_AvailableFileTypes;

        /// <summary>
        /// 所有课程系列
        /// </summary>
        private List<CourseCatalog> m_CourseSeries;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"></param>
        /// <param name="availableFileTypes"></param>
        public CourseService(string path, List<FileType> availableFileTypes)
        {
            m_InfoXmlPath = path;
            m_AvailableFileTypes = availableFileTypes;
        }

        /// <summary>
        /// 加载课程
        /// </summary>
        public void LoadCourses()
        {
            m_Courses = GetNewCourses();
        }

        /// <summary>
        /// 获取新课程
        /// </summary>
        /// <returns></returns>
        public List<Course> GetNewCourses()
        {
            var result = new List<Course>();
            var doc = new XmlDocument();

            doc.Load(m_InfoXmlPath);

            if (doc.DocumentElement != null)
            {
                var nodes = doc.DocumentElement.ChildNodes;
                foreach (XmlNode node in nodes)
                {
                    var newCourse = new Course {EventID = node.SelectSingleNode("newsID").InnerText};
                    if (m_Courses == null || !m_Courses.Contains(newCourse))
                    {
                        newCourse.EventID = node.SelectSingleNode("newsID").InnerText;
                        int index;
                        newCourse.Headline = GetHeadline(node, out index);
                        newCourse.CourseIndex = index;
                        newCourse.Description = node.SelectSingleNode("description").InnerText;
                        newCourse.Series = GetAttributeValue(node, "series");
                        newCourse.Products = GetAttributeValue(node, "products");
                        newCourse.Technology = GetAttributeValue(node, "tech");
                        newCourse.Speaker = GetAttributeValue(node, "speaker");
                        
                        newCourse.Date = DateTime.Parse(GetAttributeValue(node, "date"));
                        newCourse.Url = node.SelectSingleNode("url").InnerText;
                        newCourse.Files = GetAvailableFiles(node);
                        result.Add(newCourse);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 获取课程可用的文件类型
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private List<FileType> GetAvailableFiles(XmlNode node)
        {
            var result = new List<FileType>();
            foreach (FileType type in m_AvailableFileTypes)
            {
                var element = node.SelectSingleNode(String.Format("a[@attCatID = '{0}']", type.ID));
                if (element == null) continue;
                if (element.Attributes["attValue"].Value == "1")
                    result.Add(type);
            }
            return result;
        }

        /// <summary>
        /// 获取所有课程列表
        /// </summary>
        /// <returns></returns>
        public List<Course> GetAllCourses()
        {
            return m_Courses ?? new List<Course>();
        }

        /// <summary>
        /// 获取所有系列课程
        /// </summary>
        /// <returns></returns>
        public List<CourseCatalog> GetCourseSeries()
        {
            if (m_Courses == null)
                return new List<CourseCatalog>();
            if (m_CourseSeries == null)
            {
                m_CourseSeries = new List<CourseCatalog>();
                foreach (Course course in m_Courses)
                {
                    var catalog = m_CourseSeries.Find((x) => x.Name == course.Series.Trim());
                    if (catalog == null)
                    {
                        catalog = new CourseCatalog { Name = course.Series.Trim(), Product = course.Products, Technology = course.Technology, Date = course.Date, Speaker = course.Speaker };
                        m_CourseSeries.Add(catalog);
                    }
                    else if (catalog.Date < course.Date)
                        catalog.Date = catalog.Date;
                    catalog.Courses.Add(course);
                }
            }
            m_CourseSeries.Sort((x, y) => y.Date.CompareTo(x.Date));
            return m_CourseSeries;
        }

        /// <summary>
        /// 获取课程标题
        /// </summary>
        /// <param name="node"></param>
        /// <param name="courseIndex"></param>
        /// <returns></returns>
        private static string GetHeadline(XmlNode node, out int courseIndex)
        {
            //TODO:不严谨
            string headline = node.SelectSingleNode("headline").InnerText;
            int index = headline.IndexOf(")：");
            index = index < 0 ? 0 : index + 2;
            string result = headline.Substring(index);
            if (index > 0)
            {
                int leftIndex = headline.IndexOf("(");
                var indexStr = headline.Substring(leftIndex + 1, index - leftIndex - 3);
                int.TryParse(indexStr, out courseIndex);
            }
            else
            {
                courseIndex = 0;
            }
            return result;
        }

        /// <summary>
        /// 获取课程属性
        /// </summary>
        /// <returns></returns>
        private static string GetAttributeValue(XmlNode node, string attributeName)
        {
            var element = node.SelectSingleNode(String.Format("a[@attCatID = '{0}']", attributeName));
            return (element != null) ? element.Attributes["attValue"].Value : "";
        }
    }
}
